﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Libreria.DAL
{
    /// <summary>
    /// Esta clase será utiliada para especificar el tipo de dato que vinculara a cada atributo de una clase
    /// con respecto de su homologo en la BD.
    /// </summary>
    [System.AttributeUsage(System.AttributeTargets.All,
                           Inherited = true,
                           AllowMultiple = false)
    ]
    public class Tipo : System.Attribute
    {
        // Atributos de la clase
        private TiposSQLServer ssTipo;
        private bool ssNombreCampoIgualNombreAtributo = true;
        private string ssNombreCampo;
        private bool esLlavePrimaria = false;
        private bool esIdentidad = false;

        // Encapsulamiento de los atributos
        public bool EsIdentidad
        {
            get { return esIdentidad; }
        }

        public bool EsLlavePrimaria
        {
            get { return esLlavePrimaria; }
        }

        public bool SsNombreCampoIgualNombreAtributo
        {
            get
            {
                if (SsNombreCampo == null)
                {
                    this.ssNombreCampoIgualNombreAtributo = true;
                }
                return ssNombreCampoIgualNombreAtributo;
            }
        }

        public string SsNombreCampo
        {
            get { return ssNombreCampo; }
        }

        public TiposSQLServer SsTipo
        {
            get { return ssTipo; }
        }

        // Listados a utilizar para evitar ambiguedad y errores de entrada de datos
        public enum TiposSQLServer
        {
            _bigint = 1,
            _numeric,
            _bit,
            _smallint,
            _decimal,
            _smallmoney,
            _int,
            _tinyint,
            _money,
            _float,
            _real,
            _date,
            _datetimeoffset,
            _datetime2,
            _smalldatetime,
            _datetime,
            _time,
            _char,
            _varchar,
            _text,
            _nchar,
            _nvarchar,
            _ntext,
            _binary,
            _varbinary,
            _image
        };

        /// <summary>
        /// Especifica el tipo de datos que debe mapear para el atributo.
        /// </summary>
        /// <param name="nombreTipo">nombre del tipo de dato según MS SQL Server</param>
        public Tipo(TiposSQLServer nombreTipo)
        {
            this.ssTipo = nombreTipo;
        }

        /// <summary>
        /// Especifica el tipo de datos que debe mapear para el atributo, debe ser
        /// utilizado cuando el nombre del campo a mapear es diferente al del atributo
        /// de la clase.
        /// </summary>
        /// <param name="nombreTipo">nombre del tipo de dato según MS SQL Server</param>
        /// <param name="nombreCampoBD">nombre del campo a mapaear en la base de datos</param>
        public Tipo(TiposSQLServer nombreTipo, string nombreCampoBD)
        {
            this.ssTipo = nombreTipo;
            this.ssNombreCampoIgualNombreAtributo = false;
            this.ssNombreCampo = nombreCampoBD;
        }

        /// <summary>
        /// Especifica el tipo de datos que debe mapear para el atributo y si hace parte
        /// de la llave primaria de la tabla.
        /// </summary>
        /// <param name="nombreTipo">nombre del tipo de dato según MS SQL Server</param>
        /// <param name="esLlavePrimaria">verdadero o falso, si hace parte de la llave primaria</param>
        /// <param name="esIdentidad">verdadero o falso, si es incremental</param>
        public Tipo(TiposSQLServer nombreTipo, bool esLlavePrimaria, bool esIdentidad)
        {
            this.ssTipo = nombreTipo;
            this.esLlavePrimaria = esLlavePrimaria;
            this.esIdentidad = esIdentidad;
        }


        /// <summary>
        /// Especifica el tipo de datos que debe mapear para el atributo, debe ser
        /// utilizado cuando el nombre del campo a mapear es diferente al del atributo
        /// de la clase y si hace parte de la llave primaria de la tabla.
        /// </summary>
        /// <param name="nombreTipo">nombre del tipo de dato según MS SQL Server</param>
        /// <param name="nombreCampoBD">nombre del campo a mapaear en la base de datos</param>
        /// <param name="esLlavePrimaria">verdadero o falso, si hace parte de la llave primaria</param>
        /// <param name="esIdentidad">verdadero o falso, si es incremental</param>
        public Tipo(TiposSQLServer nombreTipo, string nombreCampoBD, bool esLlavePrimaria, bool esIdentidad)
        {
            this.ssTipo = nombreTipo;
            this.ssNombreCampoIgualNombreAtributo = false;
            this.ssNombreCampo = nombreCampoBD;
            this.esLlavePrimaria = esLlavePrimaria;
            this.esIdentidad = esIdentidad;
        }
    }
}
